#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

/** Data Structures **/

struct address {
 char *name;
 char *address;
 char *phone; };

struct list_element {
 struct list_element *prev;
 struct list_element *next;
 struct address *addr; };

struct list {
 struct list_element *first;
 struct list_element *last; };
/* --- Extra Functionality ---*/

void *my_malloc (size_t s)
 {
  void *s1;
  s1 = malloc(s);
  assert(s1!=NULL);
  return s1;
 }
/* --- List Implementation ------------------------------------------------ */

struct list_element *list_new_elem (struct address *addr)
 {
  struct list_element *elem;

  elem = my_malloc (sizeof (struct list_element));
  //assert(elem!=NULL);
  //if (!elem) { return (NULL); }

  elem->prev = elem;
  elem->next = elem;
  elem->addr = addr;

  return (elem);
 }

struct list *list_new (void)
 {
  struct list *list = my_malloc (sizeof (struct list));;
  //assert(list!=NULL);
  //if (!list) { return (NULL); }
  list->first = NULL;
  list->last  = NULL;

  return (list);
 }

void list_append (struct list *list, struct address *addr)
 {
  struct list_element *elem = NULL;

//  if (!list) { return; }
  assert(list!=NULL);
  elem = list_new_elem(addr);
 // if (!elem) { return; }
  assert(elem!=NULL);
  if (list->first == NULL && list->last == NULL)
   {
    list->first = elem;
    list->last  = elem;
    elem->prev  = elem;
    elem->next  = elem;
   }
   else
   {
    elem->prev = list->last;
    elem->next = list->first;
    list->last->next = elem;
    list->first->prev = elem;
    list->last = elem;
   }

  return;
 }

void list_remove (struct list *list, struct list_element *elem)
 {
  if (!elem || !list) { return; }

  if (elem == list->first && elem == list->last)
   {
    list->first = NULL;
    list->last  = NULL;
   }
   else if (elem == list->first)
   {
    list->first = elem->next;
    list->first->prev = list->last;
   }
   else if (elem == list->last)
   {
    list->last = elem->prev;
    list->last->next = list->first;
   }
   else
   {
    elem->prev->next = elem->next;
    elem->next->prev = elem->prev;
   }

  free (elem->addr);
  free (elem);

  return;
 }

void list_release (struct list *list)
 {
  struct list_element *elem;

  if (!list) { return; }

  elem = list->first;
  while (elem)
   {
    list_remove (list, elem);
    elem = list->first;
   }

  free (list);

  return;
 }
int main(){
	struct list *newlist = list_new();
	int i ;
	for(i=0;i<5;++i){
		struct address *addr;
		addr = my_malloc (sizeof(struct address));
		addr->name    = "NAME";
		addr->address = "Addres";
  		addr->phone   = "PHONE";
		list_append(newlist,addr);
	}
	//for(i=0;i<50;++i){
		//list_release(newlist);	
	//}	
	return 1;
}

